package com.gable.report.service.impl;


import com.gable.report.common.util.CalculationUtil;
import com.gable.report.common.util.ReturnResultUtil;
import com.gable.report.dao.IChartsForAreaCostDao;
import com.gable.report.model.ChartsAreaQuery;
import com.gable.report.model.ChartsForCost;
import com.gable.report.model.QueryInterval;
import com.gable.report.model.User;
import com.gable.report.service.ChartsForAreaCostService;
import com.gable.report.thread.RedisListStoreThread;
import com.gable.report.thread.RedisValueStoreThread;
import com.gable.report.util.RedisUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.gable.report.util.ChartsUtil.*;
import static com.gable.report.util.RedisUtil.getAreaModuleKey;
import static com.gable.report.util.RedisUtil.getListValue;


/**
 * Created by lvdouStart on 2017/7/26.
 * 区报表维修情况service实现类
 */
@Service
public class ChartsForAreaCostServiceImpl implements ChartsForAreaCostService {

    private final Log logger = LogFactory.getLog(this.getClass());

    @Autowired
    IChartsForAreaCostDao chartsForAreaCostDao;

    @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public ReturnResultUtil queryHospitals(User user, ChartsAreaQuery chartsAreaQuery) {
        try {
            Map<String,Object> paramMap = getParamMap(user, chartsAreaQuery);
            List<ChartsForCost> chartsFoCosts;
            //redis未宕机且没有筛选的情况
            if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
                //查询redis中是否有该缓存
                String key = getAreaModuleKey("cost",user,"hospital",chartsAreaQuery);
                chartsFoCosts = getListValue(redisTemplate,key);
                if(chartsFoCosts == null){
                    //设备型号数据
                    chartsFoCosts = chartsForAreaCostDao.queryHospitals(paramMap);
                    new Thread(new RedisListStoreThread(redisTemplate,key,chartsFoCosts)).start();
                }
            }else{
                chartsFoCosts = chartsForAreaCostDao.queryHospitals(paramMap);
            }
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("list",chartsFoCosts);
            if(!CollectionUtils.isEmpty(chartsFoCosts)){
                pushAvgValue(chartsFoCosts.size(),chartsFoCosts,map);
            }
            return new ReturnResultUtil(1,"success",map);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }

    @Override
    public ReturnResultUtil queryDeviceTypes(User user,ChartsAreaQuery chartsAreaQuery) {
        try {
            Map<String,Object> paramMap = getParamMap(user, chartsAreaQuery);
            List<ChartsForCost> chartsFoCosts;
            //redis未宕机且没有筛选的情况
            if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
                //查询redis中是否有该缓存
                String key = getAreaModuleKey("cost",user,"type",chartsAreaQuery);
                chartsFoCosts = getListValue(redisTemplate,key);
                if(chartsFoCosts == null){
                    //设备型号数据
                    chartsFoCosts = chartsForAreaCostDao.queryDeviceTypes(paramMap);
                    new Thread(new RedisListStoreThread(redisTemplate,key,chartsFoCosts)).start();
                }
            }else{
                chartsFoCosts = chartsForAreaCostDao.queryDeviceTypes(paramMap);
            }
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("list",chartsFoCosts);
            if(!CollectionUtils.isEmpty(chartsFoCosts)){
                //二级68分类数量之和
                int size = chartsFoCosts.stream().map((x)->x.getList() == null ? 1 : x.getList().size()).reduce(0,Integer::sum);
                pushAvgValue(size,chartsFoCosts,map);
            }
            return new ReturnResultUtil(1,"success",map);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }

    @Override
    public ReturnResultUtil queryBrand(User user,ChartsAreaQuery chartsAreaQuery) {
        try {
            Map<String,Object> paramMap = getParamMap(user, chartsAreaQuery);
            List<ChartsForCost> chartsFoCosts;
            //redis未宕机且没有筛选的情况
            if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
                //查询redis中是否有该缓存
                String key = getAreaModuleKey("cost",user,"brand",chartsAreaQuery);
                chartsFoCosts = getListValue(redisTemplate,key);
                if(chartsFoCosts == null){
                    //设备型号数据
                    chartsFoCosts = chartsForAreaCostDao.queryBrand(paramMap);
                    new Thread(new RedisListStoreThread(redisTemplate,key,chartsFoCosts)).start();
                }
            }else{
                chartsFoCosts = chartsForAreaCostDao.queryBrand(paramMap);
            }
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("list",chartsFoCosts);
            if(!CollectionUtils.isEmpty(chartsFoCosts)){
                pushAvgValue(chartsFoCosts.size(),chartsFoCosts,map);
            }
            return new ReturnResultUtil(1,"success",map);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }

    @Override
    public ReturnResultUtil queryDeviceModels(User user,ChartsAreaQuery chartsAreaQuery) {
        try {
            Map<String,Object> paramMap = getParamMap(user, chartsAreaQuery);
            List<ChartsForCost> chartsFoCosts;
            //redis未宕机且没有筛选的情况
            if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
                //查询redis中是否有该缓存
                String key = getAreaModuleKey("cost",user,"model",chartsAreaQuery);
                chartsFoCosts = getListValue(redisTemplate,key);
                if(chartsFoCosts == null){
                    //设备型号数据
                    chartsFoCosts = chartsForAreaCostDao.queryDeviceModels(paramMap);
                    new Thread(new RedisListStoreThread(redisTemplate,key,chartsFoCosts)).start();
                }
            }else{
                chartsFoCosts = chartsForAreaCostDao.queryDeviceModels(paramMap);
            }
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("list",chartsFoCosts);
            if(!CollectionUtils.isEmpty(chartsFoCosts)){
                pushAvgValue(chartsFoCosts.size(),chartsFoCosts,map);
            }
            return new ReturnResultUtil(1,"success",map);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }

    @Override
    public ReturnResultUtil queryOverview(User user,ChartsAreaQuery chartsAreaQuery) {
        try {
            Map<String,Object> paramMap = getParamMap(user, chartsAreaQuery);
            //清空接口误传的筛选值
            chartsAreaQuery.setQueryMax(null);
            chartsAreaQuery.setQueryMin(null);
            //设置默认收支比区间
            getDefaultInterval(user,paramMap);
            Map overviewMap_1;
            Map overviewMap_2;
            Map overviewMap_3;
            Map overviewMap_4;
            if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)) {
                //医院overview 4个key
                String key1 = getAreaModuleKey("cost",user,"overview_1",chartsAreaQuery);
                String key2 = getAreaModuleKey("cost",user,"overview_2",chartsAreaQuery);
                String key3 = getAreaModuleKey("cost",user,"overview_3",chartsAreaQuery);
                String key4 = getAreaModuleKey("cost",user,"overview_4",chartsAreaQuery);

                overviewMap_1 = RedisUtil.getValue(redisTemplate, key1);
                overviewMap_2 = RedisUtil.getValue(redisTemplate, key2);
                overviewMap_3 = RedisUtil.getValue(redisTemplate, key3);
                overviewMap_4 = RedisUtil.getValue(redisTemplate, key4);

                if(overviewMap_1 == null){
                    overviewMap_1 = chartsForAreaCostDao.queryOverview_1(paramMap);
                    overviewMap_2 = chartsForAreaCostDao.queryOverview_2(paramMap);
                    overviewMap_3 = chartsForAreaCostDao.queryOverview_3(paramMap);
                    overviewMap_4 = chartsForAreaCostDao.queryOverview_4(paramMap);
                    new Thread(new RedisValueStoreThread(redisTemplate, key1, overviewMap_1)).start();
                    new Thread(new RedisValueStoreThread(redisTemplate, key2, overviewMap_2)).start();
                    new Thread(new RedisValueStoreThread(redisTemplate, key3, overviewMap_3)).start();
                    new Thread(new RedisValueStoreThread(redisTemplate, key4, overviewMap_4)).start();
                }
            }else{
                overviewMap_1 = chartsForAreaCostDao.queryOverview_1(paramMap);
                overviewMap_2 = chartsForAreaCostDao.queryOverview_2(paramMap);
                overviewMap_3 = chartsForAreaCostDao.queryOverview_3(paramMap);
                overviewMap_4 = chartsForAreaCostDao.queryOverview_4(paramMap);
            }


            Map nullmap = new HashMap();
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("overview_1",overviewMap_1==null?nullmap:overviewMap_1);
            map.put("overview_2",overviewMap_2==null?nullmap:overviewMap_2);
            map.put("overview_3",overviewMap_3==null?nullmap:overviewMap_3);
            map.put("overview_4",overviewMap_4==null?nullmap:overviewMap_4);

            Map<String,Object> resultMap = new HashMap<String,Object>();
            resultMap.put("list",map);
            return new ReturnResultUtil(1,"success",resultMap);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }

    @Override
    public ReturnResultUtil queryAssets(User user,ChartsAreaQuery chartsAreaQuery) {
        try {
            Map<String,Object> paramMap = getParamMap(user, chartsAreaQuery);
            List<ChartsForCost> chartsFoCosts;
            //redis未宕机且没有筛选的情况
            if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
                //查询redis中是否有该缓存
                String key = getAreaModuleKey("cost",user,"assets",chartsAreaQuery);
                chartsFoCosts = getListValue(redisTemplate,key);
                if(chartsFoCosts == null){
                    //具体设备数据
                    chartsFoCosts = chartsForAreaCostDao.queryAssets(paramMap);
                    new Thread(new RedisListStoreThread(redisTemplate,key,chartsFoCosts)).start();
                }
            }else{
                chartsFoCosts = chartsForAreaCostDao.queryAssets(paramMap);
            }
            Map<String,Object> map = new HashMap<String,Object>();
            map.put("list",chartsFoCosts);
            return new ReturnResultUtil(1,"success",map);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }

    @Override
    public ReturnResultUtil queryForMonth(User user,ChartsAreaQuery chartsAreaQuery) {
        try {
            Map<String,Object> paramMap = getParamMap(user, chartsAreaQuery);
            //今年数据
            Integer curYear = Integer.parseInt(paramMap.get("curYear").toString());
            if(curYear == LocalDate.now().getYear()){
                paramMap.put("month",LocalDate.now().getMonthValue());
            }
            List<Map<String,Object>> list ;
            //redis未宕机且没有筛选的情况
            if(RedisUtil.isOn && isQueryNullOrOnlyType(chartsAreaQuery)){
                //查询redis中是否有该缓存
                String key = getAreaModuleKey("cost",user,"month",chartsAreaQuery);
                list = getListValue(redisTemplate,key);
                if(list == null){
                    //具体设备数据
                    list = chartsForAreaCostDao.queryForMonth(paramMap);
                    new Thread(new RedisListStoreThread(redisTemplate,key,list)).start();
                }
            }else{
                list = chartsForAreaCostDao.queryForMonth(paramMap);
            }
            return new ReturnResultUtil(1,"success",list);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }

    @Override
    public ReturnResultUtil queryInterval(Map<String, Object> map) {
        try {
            QueryInterval qi = chartsForAreaCostDao.queryInterval(map);
            if(qi == null){
                map.put("id",1001);
                qi = chartsForAreaCostDao.queryInterval(map);
            }
            return new ReturnResultUtil(1,"success",qi);
        } catch (Exception e) {
            e.printStackTrace();
            return new ReturnResultUtil(0,"查询异常");
        }
    }


    //平均值
    public void pushAvgValue(Integer num,List<ChartsForCost> chartsForCosts,Map<String,Object> map){
        String totalIncome = "0";
        String totalExpenditure = "0";
        String szPercentage = "0";
        String totalAssetsAmount = "0";

        for(ChartsForCost cfs : chartsForCosts){
            totalIncome = CalculationUtil.addForCost(totalIncome,cfs.getJnIncome().toString());
            totalExpenditure = CalculationUtil.addForCost(totalExpenditure,cfs.getJnExpenditure().toString());
            szPercentage = CalculationUtil.addForCost(szPercentage,cfs.getJnszPercentage().toString());
            totalAssetsAmount = CalculationUtil.addForCost(totalAssetsAmount,cfs.getJnAssetsAmount().toString());
        }

        String avgIncome = CalculationUtil.divide(totalIncome,num,3);
        String avgExpenditure = CalculationUtil.divide(totalExpenditure,num,3);
        String avgSzPercentage = CalculationUtil.divide(szPercentage,num,3);
        String avgAssetsAmount = CalculationUtil.divide(totalAssetsAmount,num,3);

        map.put("avgIncome",avgIncome); //平均收入
        map.put("avgExpenditure",avgExpenditure);   //平均支出
        map.put("avgSzPercentage",avgSzPercentage); //平均收支比
        map.put("avgAssetsAmount",avgAssetsAmount); //平均设备金额
    }

    /**
     * @Author: 杨青桦
     * @Description: 获取该区域收支比区间
     * @Date: 2018/6/13 14:02
     * @param user
     * @param paramMap
     */
    public void getDefaultInterval(User user,Map paramMap){
        Map<String, Object> map = new HashMap<>();
        map.put("id",userRegionMap.get(user.getId()));
        map.put("type",2);
        QueryInterval qi = chartsForAreaCostDao.queryInterval(map);
        if(qi == null){
            map.put("id",1001);
            qi = chartsForAreaCostDao.queryInterval(map);
        }
        paramMap.put("queryMax",qi.getQueryMax());
        paramMap.put("queryMin",qi.getQueryMin());
    }
}
